/**
 * HtmlParser解析工具
 */
package com.cnfangmao.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.LinkedList;
import java.util.List;

import org.apache.log4j.Logger;
import org.htmlparser.Node;
import org.htmlparser.Parser;
import org.htmlparser.Text;
import org.htmlparser.tags.OptionTag;
import org.htmlparser.tags.ScriptTag;
import org.htmlparser.tags.StyleTag;
import org.htmlparser.visitors.TextExtractingVisitor;


public class HtmlParserUtil {
	private static Logger logger = Logger.getLogger(HtmlParserUtil.class); 

	private static class ContentTextVisitor extends TextExtractingVisitor
	{
		@Override
		public void visitStringNode(Text string) {
			// TODO Auto-generated method stub
			
			Node parent=string.getParent();
			if (!(parent!=null && (  parent instanceof ScriptTag || parent instanceof OptionTag || parent instanceof StyleTag)))
			{
				super.visitStringNode(string);
			}
		}
	}
	
	/***
	 * 得到html对应的纯内容文本
	 * @param strHtml
	 * @return
	 */
	private static String getContentText4Html(String strHtml)
	{
		String strText="";
		
		try 
		{
			Parser parser = new Parser(strHtml);
			if (!(parser.getEncoding().equalsIgnoreCase("GBK") || parser.getEncoding().equalsIgnoreCase("GB2312") || 
					parser.getEncoding().equalsIgnoreCase("UTF-8")))
			{
				parser.setEncoding("UTF-8");
			}
			else
			{
				parser.setEncoding(parser.getEncoding());
			}
			
			ContentTextVisitor vistor=new ContentTextVisitor();
			parser.visitAllNodesWith(vistor);
			
			strText=vistor.getExtractedText();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
		}


		return strText;
	}
	
	/****
	 * 对html进行预处理
	 * @param strHtml
	 * @return
	 */
	private static String PreProcessHtml(String strHtml)
	{
		String strProcessedHtml=strHtml;
		strProcessedHtml=strProcessedHtml.toLowerCase();
		strProcessedHtml=strProcessedHtml.replaceAll("\n", "");
		
		strProcessedHtml=strProcessedHtml.replaceAll("</h1", " </h1");
		strProcessedHtml=strProcessedHtml.replaceAll("</h2", " </h2");
		strProcessedHtml=strProcessedHtml.replaceAll("</h3", " </h3");
		strProcessedHtml=strProcessedHtml.replaceAll("</h4", " </h4");

		//strProcessedHtml=strProcessedHtml.replaceAll("<br", " \n<br");
		//strProcessedHtml=strProcessedHtml.replaceAll("</p", "\n</p");
		//strProcessedHtml=strProcessedHtml.replaceAll("<p", "\n<p");
		strProcessedHtml=strProcessedHtml.replaceAll("。", " 。");
		//strProcessedHtml=strProcessedHtml.replaceAll("<li", "\n<li");
		//strProcessedHtml=strProcessedHtml.replaceAll("</li", "\n</li");
		strProcessedHtml=strProcessedHtml.replaceAll("<td", " [列]<td");
		strProcessedHtml=strProcessedHtml.replaceAll("</td", " [列结束]</td");
		
		strProcessedHtml=strProcessedHtml.replaceAll("<th", " [列]<th");
		strProcessedHtml=strProcessedHtml.replaceAll("<tr", " \n[行开始]\n<tr");
		strProcessedHtml=strProcessedHtml.replaceAll("</tr", " \n[行结束]\n</tr");
		strProcessedHtml=strProcessedHtml.replaceAll("<table", " \n[表开始]\n<table");
		strProcessedHtml=strProcessedHtml.replaceAll("</table", " \n[表结束]\n</table");

		strProcessedHtml=strProcessedHtml.replaceAll("\\\\r", "");
		strProcessedHtml=strProcessedHtml.replaceAll("\\\\n", "");
		strProcessedHtml=strProcessedHtml.replaceAll("\\\\t", "");
		

		return strProcessedHtml;
	}
	
	/****
	 * 将纯文本内容截成短语
	 * @param strText
	 * @return
	 */
	public static List<String> getData(String strText,String strTableHeader)
	{
		List<String> lstRows=new LinkedList<String>();
		List<String> lstLines=new LinkedList<String>();
		BufferedReader bf=new BufferedReader(new StringReader(strText));
		
		try 
		{
			String strLine="";
			String strRow="";
			
			boolean bLineBegin=false;
			
			while((strLine=bf.readLine())!=null)
			{
				strLine=strLine.trim();
				if (!strLine.isEmpty())
				{
					strLine=strLine.replaceAll("\t", " ").replaceAll("　"," ").replaceAll(" ", " ").trim();
					//lstLines.add(strLine);
					
					if (strLine.equalsIgnoreCase("[表开始]") || strLine.equalsIgnoreCase("[表结束]"))
					{
						if (!strRow.isEmpty())
						{
							lstLines.add(strRow);
							strRow="";
						}
						lstLines.add(strLine);
					}
					else if (strLine.equalsIgnoreCase("[行开始]"))
					{
						if (!strRow.isEmpty())
						{
							lstLines.add(strRow);
							strRow="";
						}
						lstLines.add(strLine);
						bLineBegin=true;
					}
					else if (strLine.equalsIgnoreCase("[行结束]"))
					{
						if (!strRow.isEmpty())
						{
							lstLines.add(strRow);
							strRow="";
						}
						lstLines.add(strLine);
						bLineBegin=false;
					}
					else if (bLineBegin)
					{
						strRow=strRow+strLine;
					}
					else
					{
						if (!strRow.isEmpty())
						{
							lstLines.add(strRow);
							strRow="";
						}
						lstLines.add(strLine);
					}
					
				}
			}
			
			boolean bTableFirst=false;
			boolean bNeedData=false;
			boolean bRowEnd=true;
			
			String[] strAryHeader=strTableHeader.split("\\|");
			int nHeaderSize=strAryHeader.length;
			String strRow1="";
			int nStartCol=0;
			int nStartCol1=0;
			
			System.out.println(strTableHeader);
			for(String strLine1:lstLines)
			{

				System.out.println(strLine1);
				if (strLine1.equalsIgnoreCase("[行开始]"))
				{
					if (!bRowEnd)
					{//连接两个行开始，不规范
						if (bTableFirst)
						{
							if (strRow.length()>1)
							{
								strRow=strRow.substring(1);
							}
							
							if (strRow.equalsIgnoreCase(strTableHeader))
							{
								nStartCol1=nStartCol;
								bNeedData=true;
								bTableFirst=false;
							}
						}
						else if(bNeedData && (strRow.indexOf("合计")==-1 && strRow.indexOf("总计")==-1 && strRow.indexOf("小计")==-1))
						{
							if (strRow.length()>5)
							{
								strRow=strRow.substring(5);
								strRow1=strRow1.substring(1);
							}
							
							if (strRow1.equalsIgnoreCase(strTableHeader))
							{
								//重复数据
								continue;
							}
							
							strAryHeader=strRow.split("\\|hjl\\|");
	 						if (strAryHeader.length==nHeaderSize)
							{
								lstRows.add(strRow);
							}
							/*else if (strAryHeader.length-1==nHeaderSize && strAryHeader[0].isEmpty())
							{//数据比设置列表多一列且第一列没有数据
								strRow=strRow.substring(5);
								lstRows.add(strRow);
							}*/
						}
					}

					strRow1="";
					strRow="";
					bRowEnd=false;

					continue;
				}
				else if(strLine1.equalsIgnoreCase("[行结束]"))
				{
					bRowEnd=true;
					if (bTableFirst)
					{
						if (strRow.length()>1)
						{
							strRow=strRow.substring(1);
						}
						
						if (strRow.equalsIgnoreCase(strTableHeader))
						{
							nStartCol1=nStartCol;
							bNeedData=true;
							bTableFirst=false;
						}
					}
					else if(bNeedData && (strRow.indexOf("合计")==-1 && strRow.indexOf("总计")==-1))
					{
						if (strRow.length()>5)
						{
							strRow=strRow.substring(5);
							strRow1=strRow1.substring(1);
						}
						
						if (strRow1.equalsIgnoreCase(strTableHeader))
						{
							//重复数据
							continue;
						}
						
						strAryHeader=strRow.split("\\|hjl\\|");
 						if (strAryHeader.length==nHeaderSize)
						{
							lstRows.add(strRow);
						}
						/*else if (strAryHeader.length-1==nHeaderSize && strAryHeader[0].isEmpty())
						{//数据比设置列表多一列且第一列没有数据
							strRow=strRow.substring(5);
							lstRows.add(strRow);
						}*/
					}
					strRow1="";
					strRow="";
					continue;
				}
				else if(strLine1.equalsIgnoreCase("[表开始]"))
				{
					bRowEnd=true;
					nStartCol=0;
					if (!bNeedData)
					{
						bTableFirst=true;
					}
					continue;
				}				
				else if(strLine1.equalsIgnoreCase("[表结束]"))
				{
				//	bNeedData=false;
					bRowEnd=true;
					nStartCol=0;
					continue;
				}
				
				String[] strAryColumn=strLine1.split("\\[列\\]");
				
				if(bTableFirst)
				{//如果是第一行，收集第一行数据

					for(int h=0;h<strAryColumn.length;h++)
					{
						String strTemp=strAryColumn[h].trim();
					
						if (strTemp.endsWith("[列结束]"))
						{
							strTemp=strTemp.substring(0, strTemp.length()-5);
							strTemp=strTemp.replaceAll(" ", "");
						}
						
						if (!strTemp.isEmpty())
						{
							strRow=strRow+"|"+strTemp;
						}
						else if (strRow.isEmpty())
						{//如果开头列为空
							nStartCol++;
						}
					}
					
					continue;
				}
				

				if (bNeedData)
				{
					boolean bValid=false;  //是否有有效数据
					for(int h=nStartCol1;h<strAryColumn.length;h++)
					{
						String strTemp=strAryColumn[h].trim();
						if (strTemp.isEmpty())
						{
							strTemp="hjlnovalue";
						}
						
						if (strTemp.endsWith("[列结束]"))
						{
							strTemp=strTemp.substring(0, strTemp.length()-5);
							String strTemp1=strTemp.replaceAll(" ", "");
							if (strTemp1.isEmpty())
							{
								strTemp="hjlnovalue";
							}
							else
							{
								bValid=true;
							}
						}
						
						if (bValid)
						{
							strRow=strRow+"|hjl|"+strTemp;
							strRow1=strRow1+"|"+strTemp;
						}
						else
						{
							strRow="";
							strRow1="";
						}
					}

				}
			}

		} catch (IOException e) {
			// TODO Auto-generated catch block
			logger.error(e);;
		}
		
		return lstRows;
	}

	public static String getContentText(String strHtml)
	{
		//解析纯内容文本
		String strResultHtml=PreProcessHtml(strHtml);

		for(int i=0;i<strResultHtml.length();i++)
		{
			if (strResultHtml.charAt(i)=='<')
			{
				strResultHtml=strResultHtml.substring(i);
				break;
			}
		}
		
		String strContent=getContentText4Html(strResultHtml);
		
		return strContent;
	}
	/****
	 * 解析一个文本
	 * @param strHtml
	 * @return
	 */
	public static List<String> ParseHtml(String strHtml,String strTableHeader)
	{
	
		String strContent=getContentText(strHtml);
		return getData(strContent,strTableHeader);
	}
	
	
}
